package XiaoNei::API;

use strict;
use LWP::UserAgent;
use XML::Simple ;
use Data::Dumper;
use XiaoNei::Utils;

use Carp qw/croak/;

use constant TARGET_API_VERSION     => "1.0";
use constant ERROR_TAG              => "error_response";
use constant XN_SERVER              => "api.xiaonei.com/restserver.do";
use constant SERVER_ADDR            => "http://" . XN_SERVER;
use constant HTTPS_SERVER_ADDR      => "https://" . XN_SERVER;


my $map_method_parse = {
    "xiaonei.auth.createToken"          => \&auth_createToken,
    "xiaonei.auth.getSession"           => \&auth_getSession,
    "xiaonei.friends.getFriends"        => \&friends_getFriends,
    "xiaonei.friends.getAppUsers"       => \&friends_getAppUsers,
    "xiaonei.friends.areFriends"        => \&friends_areFriends,
    "xiaonei.users.getInfo"             => \&users_getInfo,
    "xiaonei.users.getLoggedInUser"     => \&users_getLoggedInUser,
    "xiaonei.users.isAppAdded"          => \&users_isAppAdded,
    "xiaonei.profile.setXNML"           => \&profile_setXNML,
    "xiaonei.profile.getXNML"           => \&profile_getXNML,
    "xiaonei.xnml.refreshRefUrl"        => \&xnml_refreshRefUrl,
    "xiaonei.xnml.setRefHandle"        => \&xnml_setRefHandle,
    "xiaonei.feed.publishStoryToUser"   => \&feed_publishStoryToUser,
    "xiaonei.feed.publishTemplatizedAction" => \&feed_publishTemplatizedAction,
    "xiaonei.notifications.send"        => \&notifications_send,
    "xiaonei.requests.sendRequest"      => \&requests_sendRequest,
    "xiaonei.friends.get"      => \&friends_get,

};

#not need sessionkey
my $map_pre_auth = {
    "xiaonei.auth.createToken"          => 1,
    "xiaonei.auth.getSession"           => 1,
};



sub auth_createToken {
    my $xml = shift;

}
sub auth_getSession {
    my $xml = shift;

}
sub friends_getFriends {
    my $xml = shift;
    if ($xml->{friend}->{name}) {
        return {
            $xml->{friend}->{name} =>  {
                id => $xml->{friend}->{id},
                headurl => $xml->{friend}->{headurl},
            }
        };
    }
    return $xml->{friend};
}
sub friends_getAppUsers {
    my $xml = shift;
    return $xml->{uid};
}
sub friends_areFriends {
    my $xml = shift;
    return $xml->{friend_info};
}
sub users_getInfo {
    my $xml = shift;
    return $xml->{user};
}
sub users_getLoggedInUser {
    my $xml = shift;
    return $xml->{content};
}
sub users_isAppAdded {
    my $xml = shift;
    return $xml->{content};
}
sub profile_setXNML {
    my $xml = shift;

}
sub profile_getXNML {
    my $xml = shift;

}

sub xnml_refreshRefUrl {
    my $xml = shift;

}
sub xnml_setRefHandle {
    my $xml = shift;

}
sub feed_publishStoryToUser {
    my $xml = shift;

}
sub feed_publishTemplatizedAction {
    my $xml = shift;

}
sub notifications_send {
    my $xml = shift;

}
sub requests_sendRequest {
    my $xml = shift;
    return $xml->{uid};
}

sub friends_get {
    my $xml = shift;
    return $xml->{uid};
}


sub call {
    my $method_name = shift;
    croak "not method exists: $method_name" if not exists $map_method_parse->{$method_name};    
    
    my $rh_param = shift;
    $rh_param->{method} = $method_name;
    $rh_param->{v} = TARGET_API_VERSION;
    
    if (not $map_pre_auth->{$method_name} and $rh_param->{session_key}) {
        $rh_param->{call_id} = time;
    }
    
    #singatrue
    #...ignore...
    if ($rh_param->{secret}) {
        $rh_param->{sig} = XiaoNei::Utils::gen_signature($rh_param, $rh_param->{secret});
    }
    
    
    my $ua = LWP::UserAgent->new;
    my $do_https = $method_name eq 'xiaonei.auth.getSession' ? 1 : 0;
    my $response = $ua->post($do_https ? HTTPS_SERVER_ADDR : SERVER_ADDR, $rh_param);

    croak "connect error" if $response->code ne '200';
    my $xml = XMLin($response->content);
    if (exists $xml->{error_code}) {
        print STDERR $response->content;
        croak "call error " .  $xml->{error_msg} . "\n";
    }
    return $map_method_parse->{$method_name}->( $xml );
}



1;
